﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;



namespace MVCnExt.Web.UI.Ext
{
    /// <summary>
    /// Dictionary of client-side object properties used to 
    /// build client-side initialization scripts
    /// </summary>
    public class ExtScriptControlDescriptor : ScriptControlDescriptorBase
    {
        public ExtScriptControlDescriptor(String type, String elementId)
            : base(type, elementId)
        {

        }

        public ExtScriptControlDescriptor(String type, String elementId, String id)
            : base(type, elementId)
        {
            this.varId = id;
        }

        /// <summary>
        /// Builds the onReady/Initialize script to load script objects
        /// on the client after the document has loaded.
        /// </summary>
        /// <param name="isStandAlone">Indicates wither or not the object being 
        /// scripted is a child of another object (ex. listed in items collection)</param>
        public override string WriteScript(ScriptType scriptType)
        {
            StringBuilder script = new StringBuilder();
            object value;         

            _properties.TryGetValue("xtype", out value);
            if (value != null)
                scriptType = ScriptType.ConfigOnly;

            // is object a child of another object            
            if (scriptType == ScriptType.StandAlone)
                script.AppendFormat("\tvar {0} = ", varId);            
            
            // overloaded constructor declaration with new            
            if (this.Overloaded)
            {                
                _properties.TryGetValue("targetID", out value);
                _properties.Remove("targetID");
                script.AppendFormat("new {0} ({1},{{", Type, value);
            }          
            //new declaration
            else if (scriptType != ScriptType.ConfigOnly)
                script.AppendFormat("new {0} ({{", Type);                      
            else
                script.Append("{");

            // script properties
            for (int i = 0; i < _properties.Count; i++)
            {
                if (i != 0)
                {
                    // separate properties
                    script.Append(",");

#if DEBUG
                    // for readability
                    script.Append("\r\n\t\t");
#endif
                }

                script.AppendFormat("{0} : {1}",
                    _properties.Keys[i],
                    GetValue(_properties[_properties.Keys[i]]));

            }

#if DEBUG
            // for readability
            script.Append("\r\n\t");
#endif

            // close definition
            if (scriptType != ScriptType.ConfigOnly)
                script.Append("})");
            else
                script.Append("}");

            // if not child object end the line
            if (scriptType == ScriptType.StandAlone)
                script.Append(";");              

#if DEBUG
            // for readability
            script.AppendLine();
#endif           
            return script.ToString();
        }

        public override string AppendScript()
        {
            StringBuilder script = new StringBuilder();
            script.Append(base.AppendScript());

            // script properties
            for (int i = 0; i < _properties.Count; i++)
            {
#if DEBUG
                    // for readability
                    script.Append("\r\n\t\t");
#endif
                script.Append(GetValue(_properties[_properties.Keys[i]]));

            }

            return script.ToString();
        }

        public override string WriteScript()
        {
            return WriteScript(ScriptType.StandAlone);
        }

        protected override string GetScript()
        {
            return WriteScript();
        }

        protected String GetValue(Object value)
        {
            switch (value.GetType().Name)
            {
                case "Boolean":
                    return value.ToString().ToLowerInvariant();
                case "String":
                    return (String)value;
                case "Int16":
                case "Int32":
                case "Int64":
                    return value.ToString();
                case "Unit":
                    if (((Unit)value).Type == UnitType.Pixel)
                        return ((Unit)value).Value.ToString("########0");
                    else
                        return String.Format("'{0}'", value);
                default:
                    return value.ToString();
            }
        }

        private String varId { get; set; }
    }
}
